home *** CD-ROM | disk | FTP | other *** search
/ Aminet 3 / Aminet 3 - July 1994.iso / Aminet / misc / unix / tracker_4_3.lzh / tracker / notes.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-13  |  3.5 KB  |  167 lines

  1. /* notes.c 
  2.     vi:se ts=3 sw=3:
  3.  */
  4.  
  5. /* $Id: notes.c,v 4.0 1994/01/11 17:50:04 espie Exp espie $
  6.  * $Log: notes.c,v $
  7.  * Revision 4.0  1994/01/11  17:50:04  espie
  8.  * Makes use of autoinit. Uses less memory, starts up faster.
  9.  *
  10.  * Revision 1.6  1994/01/09  17:36:22  Espie
  11.  * Generalized open.c.
  12.  *
  13.  * Revision 1.5  1994/01/08  03:55:43  Espie
  14.  * auto_init'd create_notes_table(),
  15.  * suppressed note_name static table,
  16.  * use name_of_note() instead (about 120 * 8 bytes gain).
  17.  *
  18.  * Revision 1.4  1994/01/05  16:10:49  Espie
  19.  * *** empty log message ***
  20.  *
  21.  * Revision 1.3  1994/01/05  14:54:09  Espie
  22.  * *** empty log message ***
  23.  *
  24.  * Revision 1.2  1994/01/05  13:50:43  Espie
  25.  * Cosmetic change.
  26.  *
  27.  * Revision 1.1  1993/12/26  00:55:53  Espie
  28.  * Initial revision
  29.  *
  30.  * Revision 3.6  1993/12/04  16:12:50  espie
  31.  * New locals
  32.  *
  33.  * Revision 3.5  1993/11/17  15:31:16  espie
  34.  * *** empty log message ***
  35.  *
  36.  * Revision 3.4  1993/11/11  20:00:03  espie
  37.  * Amiga support.
  38.  *
  39.  * Revision 3.2  1992/11/20  14:53:32  espie
  40.  * Added finetune.
  41.  *
  42.  * Revision 3.1  1992/11/19  20:44:47  espie
  43.  * Protracker commands.
  44.  *
  45.  * Revision 3.0  1992/11/18  16:08:05  espie
  46.  * New release.
  47.  *
  48.  */
  49.  
  50. #include "defs.h"
  51.  
  52. #ifdef MALLOC_NOT_IN_STDLIB
  53. #include <malloc.h>
  54. #else
  55. #include <stdlib.h>
  56. #endif
  57. #include <stdio.h>
  58. #include <string.h>
  59. #include <ctype.h>
  60. #include <assert.h>
  61. #include <math.h>
  62.  
  63. #include "song.h"
  64. #include "channel.h"
  65. #include "extern.h"
  66.  
  67. ID("$Id: notes.c,v 4.0 1994/01/11 17:50:04 espie Exp espie $")
  68.  
  69.  
  70. /* we can put it autoinit since find_note is ALWAYS called
  71.  * prior to finding note values !
  72.  */
  73. LOCAL void create_notes_table P((void));
  74. LOCAL void (*INIT)P((void)) = create_notes_table;
  75.  
  76.  
  77. /* the musical notes correspond to some specific pitch.
  78.  * It's useful to be able to find them back, at least for
  79.  * arpeggii.
  80.  */
  81. short pitch_table[NUMBER_NOTES][NUMBER_FINETUNES];
  82.  
  83. LOCAL char *note_template = "C-C#D-D#E-F-F#G-G#A-A#B-";
  84.  
  85. /* find_note(pitch): find note corresponding to the stated pitch */
  86. int find_note(pitch)
  87. int pitch;
  88.    {
  89.    int a, b, i;
  90.    
  91.    INIT_ONCE;
  92.  
  93.    if (pitch == 0)
  94.       return -1;
  95.    a = 0;
  96.    b = NUMBER_NOTES-1;
  97.    while(b-a > 1)
  98.       {
  99.       i = (a+b)/2;
  100.       if (pitch_table[i][0] == pitch)
  101.          return i;
  102.       if (pitch_table[i][0] > pitch)
  103.          a = i;
  104.       else
  105.          b = i;
  106.       }
  107.    if (pitch_table[a][0] - FUZZ <= pitch)
  108.       return a;
  109.    if (pitch_table[b][0] + FUZZ >= pitch)
  110.       return b;
  111.    return NO_NOTE;
  112.    }
  113.  
  114. LOCAL void create_notes_table()
  115.    {
  116.    double base, pitch;
  117.    int i, j, k;
  118.  
  119.    for (j = -8; j < 8; j++)
  120.       {
  121.       k = j < 0 ? j + 16 : j;
  122.       base = AMIGA_CLOCKFREQ/440.0/4.0 / pow(2.0, j/96.0);
  123.  
  124.       for (i = 0; i < NUMBER_NOTES; i++)
  125.          {
  126.          pitch = base / pow(2.0, i/12.0);
  127.          pitch_table[i][k] = floor(pitch + 0.5);
  128.          }
  129.       }
  130.     }
  131.  
  132. char *name_of_note(i)
  133. int i;
  134.    {
  135.    static char name[4];
  136.  
  137.    if (i == NO_NOTE)
  138.       return "   ";
  139.    else 
  140.       {
  141.       name[0] = note_template[(i+9)%12 * 2];
  142.       name[1] = note_template[(i+9)%12 * 2 +1];
  143.       name[2] = '0' + (i-3)/12;
  144.       name[3] = 0;
  145.       return name;
  146.       }
  147.    }
  148.    
  149. int transpose_song(s, transpose)
  150. struct song *s;
  151. int transpose;
  152.    {
  153.    int oldt;
  154.    int i, j, n;
  155.  
  156.    if (!s)
  157.       return 0;
  158.    oldt = s->info.transpose;
  159.    for (n = 0; n < s->info.maxpat; n++)
  160.       for (i = 0; i < BLOCK_LENGTH; i++)
  161.          for (j = 0; j < NUMBER_TRACKS; j++)
  162.             if (s->info.pblocks[n].e[j][i].note != NO_NOTE)
  163.                s->info.pblocks[n].e[j][i].note += transpose - oldt;
  164.    s->info.transpose = transpose;
  165.    return oldt;
  166.    }
  167.